package com.ruoyi.asms.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.ams.controller.AmsOwnAddressController;
import com.ruoyi.asms.domain.AsmsMaintenanceAsset;
import com.ruoyi.asms.domain.AsmsOwnAddressAssetCode;
import com.ruoyi.asms.domain.vo.AsmsMaintenanceAssetAddVo;
import com.ruoyi.asms.domain.vo.AsmsMaintenanceAssetEditVo;
import com.ruoyi.asms.domain.vo.MaintenanceAssetInfoVo;
import com.ruoyi.asms.service.IAsmsAssetFullInfoService;
import com.ruoyi.asms.service.IAsmsMaintenanceAssetService;
import com.ruoyi.asms.service.IAsmsOwnAddressAssetCodeService;
import com.ruoyi.asms.service.AsmsReusingService;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.rabbitmq.constant.RabbitmqConstants;
import com.ruoyi.common.rabbitmq.domain.EmailNotifyTemplate;
import com.ruoyi.common.rabbitmq.utils.NotifyUtils;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.security.service.TokensService;
import com.ruoyi.system.controller.SysUserController;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * 维护方维护资产信息Controller
 *
 * @author yfkj
 * @date 2021-10-21
 */
@RestController
@RequestMapping("/asms/AsmsMaintenanceAsset")
public class AsmsMaintenanceAssetController extends BaseController {
    @Autowired
    private IAsmsMaintenanceAssetService asmsMaintenanceAssetService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
    @Autowired
    private AsmsReusingService asmsReusingService;
    @Autowired
    private IAsmsOwnAddressAssetCodeService asmsOwnAddressAssetCodeService;
    @Autowired
    private TokensService tokenService;
    @Autowired
    RabbitTemplate rabbitTemplate;

//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteAssetAddressService remoteAssetAddressService;
    @Autowired
    SysUserController userController;
    @Autowired
    AmsOwnAddressController ownAddressController;
    /**
     * 查询维护方维护资产信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:list")
    @GetMapping("/list")
    public TableDataInfo list(AsmsMaintenanceAsset asmsMaintenanceAsset) {
        jdbcTemplate.queryForList("");
        startPage();
        List<AsmsMaintenanceAsset> list = asmsMaintenanceAssetService.selectAsmsMaintenanceAssetList(asmsMaintenanceAsset);
        return getDataTable(list);
    }

    /**
     * 导出维护方维护资产信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:export")
    @Log(title = "维护方维护资产信息", businessType = BusinessType.EXPORT)
    @PostMapping(value="/export", produces = "application/octet-stream")
    public void export(HttpServletResponse response, AsmsMaintenanceAsset asmsMaintenanceAsset) throws IOException {
        List<AsmsMaintenanceAsset> list = asmsMaintenanceAssetService.selectAsmsMaintenanceAssetList(asmsMaintenanceAsset);
        ExcelUtil<AsmsMaintenanceAsset> util = new ExcelUtil<AsmsMaintenanceAsset>(AsmsMaintenanceAsset.class);
        util.exportExcel(response, list, "维护方维护资产信息数据");
    }

    /**
     * 获取维护方维护资产信息详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:query")
    @GetMapping(value = "/{maintenanceAssetId}")
    public AjaxResult getInfo(@PathVariable("maintenanceAssetId") Long maintenanceAssetId) {
        return AjaxResult.success(asmsMaintenanceAssetService.selectAsmsMaintenanceAssetByMaintenanceAssetId(maintenanceAssetId));
    }

    /**
     * 新增维护方维护资产信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:add")
    @Log(title = "维护方维护资产信息", businessType = BusinessType.INSERT)
    @PostMapping("/addAsmsMaintenanceAssetAdd")
    @ApiOperation("新增资产售后维护信息")
    @Transactional
    public AjaxResult add(@RequestBody AsmsMaintenanceAssetAddVo asmsMaintenanceAssetAddVo) {
        AsmsMaintenanceAsset asmsMaintenanceAsset = new AsmsMaintenanceAsset();
        BeanUtils.copyProperties(asmsMaintenanceAssetAddVo, asmsMaintenanceAsset);
        asmsMaintenanceAsset.setBindUserId(SecurityUtils.getUserId());
        asmsMaintenanceAssetService.save(asmsMaintenanceAsset);

        AsmsAssetFullInfo asmsAssetFullInfo = asmsReusingService.setAssetInfo(asmsMaintenanceAssetAddVo);
        asmsAssetFullInfo.setMaintenanceAssetId(asmsMaintenanceAsset.getMaintenanceAssetId());
        AsmsAssetFullInfo info = asmsAssetFullInfoService.getOne(new QueryWrapper<AsmsAssetFullInfo>()
                .eq(AsmsAssetFullInfo.ASSET_ID, asmsMaintenanceAssetAddVo.getAssetId()), false);
        asmsAssetFullInfo.setId(info.getId());
        asmsAssetFullInfoService.updateById(asmsAssetFullInfo);

        AsmsOwnAddressAssetCode code = new AsmsOwnAddressAssetCode();
        code.setCode(asmsMaintenanceAssetAddVo.getCode());
        code.setAddressId(info.getAddressId());
        code.setAssetId(asmsMaintenanceAssetAddVo.getAssetId());
        code.setDeptId(info.getOwnDeptId());
        code.setCreateBy(SecurityUtils.getUsername());
        code.setCreateTime(System.currentTimeMillis());
        asmsOwnAddressAssetCodeService.save(code);

        return AjaxResult.success("新增成功！");
    }

    /**
     * 修改维护方维护资产信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:edit")
    @Log(title = "维护方维护资产信息", businessType = BusinessType.UPDATE)
    @PutMapping("/editAsmsMaintenanceAsset")
    @ApiOperation("修改资产售后维护信息")
    @Transactional
    public AjaxResult edit(@RequestBody AsmsMaintenanceAssetEditVo asmsMaintenanceAssetEditVo) {
        AsmsMaintenanceAsset asmsMaintenanceAsset = new AsmsMaintenanceAsset();
        BeanUtils.copyProperties(asmsMaintenanceAssetEditVo, asmsMaintenanceAsset);
        asmsMaintenanceAssetService.updateAsmsMaintenanceAsset(asmsMaintenanceAsset);

        AsmsAssetFullInfo asmsAssetFullInfo = asmsReusingService.setAssetInfo(asmsMaintenanceAssetEditVo);
        AsmsAssetFullInfo info = asmsAssetFullInfoService.getOne(new QueryWrapper<AsmsAssetFullInfo>()
                .eq(AsmsAssetFullInfo.ASSET_ID, asmsMaintenanceAssetEditVo.getAssetId()), false);
        if (info == null){
            return AjaxResult.error("未找到资产设备信息！");
        }
        asmsAssetFullInfo.setId(info.getId());
        asmsAssetFullInfoService.updateById(asmsAssetFullInfo);

        AsmsOwnAddressAssetCode code = new AsmsOwnAddressAssetCode();
        code.setCode(asmsMaintenanceAssetEditVo.getCode());
        code.setAddressId(info.getAddressId());
        code.setDeptId(info.getOwnDeptId());
        code.setUpdateBy(SecurityUtils.getUsername());
        code.setUpdateTime(System.currentTimeMillis());
        code.setAddressCodeId(asmsMaintenanceAssetEditVo.getAddressCodeId());
        asmsOwnAddressAssetCodeService.updateById(code);

        /**
         * 资产维护信息变更通知  使用部门所属部门   角色（资产管理部门负责人）  内容：   SecurityUtils 某人 变更了 某地某类型资产维护信息
         */

        Long useDeptId = info.getUseDeptId();
        Long ownDeptId = info.getOwnDeptId();

        List<Long> deptIds = new LinkedList<>();
        deptIds.add(useDeptId);
        deptIds.add(ownDeptId);

        R<List<SysUser>> rDeptManegers = userController.getDeptManegersByDeptIds(deptIds);

        if(rDeptManegers !=null) {
            Set<Object> notifyUsers = new HashSet<>();
            if (rDeptManegers.getData() != null && rDeptManegers.getData().size() > 0) {
                notifyUsers.addAll(rDeptManegers.getData());
            }
            StringBuilder content = new StringBuilder();

            content.append(SecurityUtils.getUsername());
            content.append(" 变更了 位于");
            content.append(info.getAddressFullName());
            content.append("的");
            content.append(info.getAssetTypeName());
            content.append("的资产维护信息");

            EmailNotifyTemplate emailNotifyTemplate = NotifyUtils.createEmailNotifyTemplate(notifyUsers, content.toString(), "小焱资管", "资产维护信息变更通知");

            rabbitTemplate.convertAndSend(RabbitmqConstants.EXCHANGE, RabbitmqConstants.EMAIL_ROUTINGKEY,emailNotifyTemplate);
        }

        return AjaxResult.success("修改成功！");
    }

    /**
     * 删除维护方维护资产信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:remove")
    @Log(title = "维护方维护资产信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{maintenanceAssetIds}")
    public AjaxResult remove(@PathVariable Long[] maintenanceAssetIds) {
        return toAjax(asmsMaintenanceAssetService.deleteAsmsMaintenanceAssetByMaintenanceAssetIds(maintenanceAssetIds));
    }

    /**
     * 获取维护资产管理的列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsMaintenanceAsset:list")
    @GetMapping("/getList")
    @ApiOperation("获取维护资产管理的列表")
    public TableDataInfo getList(AsmsAssetFullInfo assetFullInfo) {
        //获取本部门的所有维护资产id
        QueryWrapper<AsmsMaintenanceAsset> wrapper1 = new QueryWrapper<>();
        Set<Long> userMaintenanceDeptIds = tokenService.getUserMaintenanceDeptIds();
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            if (userMaintenanceDeptIds != null && userMaintenanceDeptIds.size() > 0) {
                wrapper1.in(AsmsMaintenanceAsset.MAINTENANCE_DEPT_ID, userMaintenanceDeptIds);
            } else {
                return getDataTable(new ArrayList<>());
            }
        }

        //构造维护资产id集合
        List<AsmsMaintenanceAsset> maintenanceAssetList = asmsMaintenanceAssetService.list(wrapper1);
        if (maintenanceAssetList == null || maintenanceAssetList.size() == 0) {
            return getDataTable(new ArrayList<>());
        }
        HashSet<Long> set = new HashSet<>();
        for (AsmsMaintenanceAsset asset : maintenanceAssetList) {
            set.add(asset.getAssetId());
        }

        QueryWrapper<AsmsAssetFullInfo> wrapper = new QueryWrapper<>();
        if (set.size() != 0) {
            wrapper.in(AsmsAssetFullInfo.ASSET_ID, set);
        }
        if (StringUtils.isNotEmpty(assetFullInfo.getAssetTypeName())) {
            wrapper.like(AsmsAssetFullInfo.ASSET_TYPE_NAME, assetFullInfo.getAssetTypeName());
        }
        if (assetFullInfo.getBrandId() != null) {
            wrapper.eq(AsmsAssetFullInfo.BRAND_ID, assetFullInfo.getBrandId());
        }
        if (assetFullInfo.getProjectId() != null) {
            wrapper.eq(AsmsAssetFullInfo.PROJECT_ID, assetFullInfo.getProjectId());
        }
        if (assetFullInfo.getOwnDeptId() != null) {
            wrapper.eq(AsmsAssetFullInfo.OWN_DEPT_ID, assetFullInfo.getOwnDeptId());
        }
        if (assetFullInfo.getAddressId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ADDRESS_ID, assetFullInfo.getAddressId());
        }
        startPage();
        List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(wrapper);
        return getDataTable(list);
    }

    /**
     * 根据assetId获取资产维护信息与位置报修码信息
     */
    @PreAuthorize
    @GetMapping("/getByAssetId")
    @ApiOperation("根据assetId获取资产维护信息与位置报修码信息")
    public AjaxResult getByAssetId(@ApiParam(value = "资产ID，从返回的列表中获取", required = true) @RequestParam("assetId") Long assetId) {
        MaintenanceAssetInfoVo assetInfoVo = new MaintenanceAssetInfoVo();
        AsmsMaintenanceAsset asmsMaintenanceAsset = asmsMaintenanceAssetService.getOne(new QueryWrapper<AsmsMaintenanceAsset>()
                .eq(AsmsMaintenanceAsset.ASSET_ID, assetId), false);
        AsmsOwnAddressAssetCode assetCode = asmsOwnAddressAssetCodeService.getOne(new QueryWrapper<AsmsOwnAddressAssetCode>()
                .eq(AsmsOwnAddressAssetCode.ASSET_ID, assetId), false);
        if (asmsMaintenanceAsset != null) {
            BeanUtils.copyProperties(asmsMaintenanceAsset, assetInfoVo);
        }
        if (assetCode != null) {
            BeanUtils.copyProperties(assetCode, assetInfoVo);
        }
        return AjaxResult.success(assetInfoVo);
    }

    /**
     * 定时检查维护到期时间，并通知资产所属部门的资产管理负责人与售后维护部门的售后维护负责人  通知过后AsmsMaintenanceAsset表的is_delete置 2  内容  某地某类型资产维护过期
     * @return
     */
    @GetMapping("/checkEndUseTime")
    public R checkEndUseTime(){

        List<AsmsMaintenanceAsset> asmsMaintenanceAssetList = asmsMaintenanceAssetService.list();
        List<Long> assetIds = new LinkedList<>();
        for(AsmsMaintenanceAsset asmsMaintenanceAsset : asmsMaintenanceAssetList){
            if(asmsMaintenanceAsset.getEndUseTime().compareTo(System.currentTimeMillis()) == -1 && asmsMaintenanceAsset.getIsDelete() == 1){
                assetIds.add(asmsMaintenanceAsset.getAssetId());
            }
        }

        List<AsmsAssetFullInfo> fullInfoList = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .in(assetIds.size() > 0, AsmsAssetFullInfo.ASSET_ID, assetIds));

        HashMap<Object,String> map=new HashMap<>();
              for(AsmsAssetFullInfo info : fullInfoList){
            Set<Object> notifyUsers = new HashSet<>();
            List<Long> ownDeptIds = new LinkedList<>();
            ownDeptIds.add(info.getOwnDeptId());
            R<List<SysUser>> rAssetManegers = userController.getDeptManegersByDeptIds(ownDeptIds);
            List<Long>  maintenanceDeptIds = new LinkedList<>();
            maintenanceDeptIds.add(info.getMaintenanceDeptId());
            R<List<SysUser>> rMaintenanceDeptManegers = userController.getMaintenanceDeptManegersByDeptIds(maintenanceDeptIds);

            if(rAssetManegers != null && rMaintenanceDeptManegers != null ){
                if(rAssetManegers.getData() != null && rAssetManegers.getData().size() > 0){
                    notifyUsers.addAll(rAssetManegers.getData());
                }
                if(rMaintenanceDeptManegers.getData() != null && rMaintenanceDeptManegers.getData().size() > 0){
                    notifyUsers.addAll(rMaintenanceDeptManegers.getData());
                }


                for(Object o : notifyUsers){
                    StringBuilder content = new StringBuilder();
                    content.append(" \n");
                    content.append(info.getAddressFullName());
                    content.append("的 ");
                    content.append(info.getAssetTypeName());
                    if(map.containsKey(o)){
                        content.append("与");
                        content.append(map.get(o));
                    }
                    map.put(o,content.toString());
                }


            }

        }
        for(Object user : map.keySet()){
            Set<Object> users = new HashSet<>();
            users.add(user);
            EmailNotifyTemplate emailNotifyTemplate = NotifyUtils.createEmailNotifyTemplate(users, map.get(user)+" 的资产维保过期,请尽快处理！", "小焱资管", "资产维保过期通知");
            rabbitTemplate.convertAndSend(RabbitmqConstants.EXCHANGE, RabbitmqConstants.EMAIL_ROUTINGKEY,emailNotifyTemplate);
        }

        return R.ok();
    }

    @GetMapping("/saveMaintenanceAssetInfo")
    public R saveMaintenanceAssetInfo(@RequestParam("maintenanceDeptId")Long maintenanceDeptId, @RequestParam("assetId")Long assetId, @RequestParam("bindUserId)")Long bindUserId){
        AsmsMaintenanceAsset maintenanceAsset = new AsmsMaintenanceAsset();
        maintenanceAsset.setMaintenanceDeptId(maintenanceDeptId);
        maintenanceAsset.setAssetId(assetId);
        maintenanceAsset.setStartUseTime(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        maintenanceAsset.setEndUseTime(1709888111000l);
        maintenanceAsset.setIsDelete(1);
        maintenanceAsset.setBindUserId(bindUserId);
        maintenanceAsset.setCreateBy("管理员");
        maintenanceAsset.setCreateTime(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        asmsMaintenanceAssetService.save(maintenanceAsset);

        return R.ok(maintenanceAsset.getMaintenanceAssetId());
    }


}
